/* eslint-disable */
// require('script-loader!file-saver');
// require('./Blob');
// require('script-loader!xlsx/dist/xlsx.core.min');
function rgb2hex(rgb) {
  var reg = /rgb\((\d{1,3}),[ ]?(\d{1,3}),[ ]?(\d{1,3})\)/;
  var arr = reg.exec(rgb);
  if (arr === null) {
    return rgb;
  }

  function hex(x) {
    return ("0" + parseInt(x).toString(16)).slice(-2);
  }
  var _hex = "#" + hex(arr[1]) + hex(arr[2]) + hex(arr[3]);
  return _hex.toUpperCase();
}

function getCellStyle(cell, opts) {
  var style = {};
  var $cell = $(cell);
  var $children = $cell.find('>*');
  if ($children.length > 0) {
    $cell = $($children[0]);
  }

  var fontSize = $cell.css('font-size');
  if (fontSize !== "") {
    var fontSize = parseInt(fontSize)
    fontSize = _.round(fontSize * 72 / 96, 1);
    style.fontSize = fontSize;
  }

  var fontFamily = $cell.css('font-family');
  if (fontFamily !== "") {
    fontFamily = fontFamily.split(',')[0].trim();
    style.fontFamily = fontFamily;
  }

  var color = $cell.css('color');
  if (color !== "") {
    color = rgb2hex(color);
    if (color.indexOf('#') === 0) {
      color = color.substring(1);
    }

    if (color !== "000000") {
      style.color = color;
    }
  }

  var align = $cell.css('text-align');
  if (align !== "") {
    if (['center', 'right'].indexOf(align) === -1) {
      align = 'left';
    }
    style.align = align;
  }

  var fontStyle = $cell.css('font-style');
  if (fontStyle !== "") {
    var italic = fontSize === 'italic';
    style.italic = italic;
  }

  var textDecoration = $cell.css('text-decoration-line');
  if (textDecoration !== "") {
    if (textDecoration === 'underline') {
      style.underline = true;
    } else if (textDecoration === 'line-through') {
      style.strike = true;
    }
  }

  var fontWeight = $cell.css('font-weight');
  if (fontWeight !== "") {
    fontWeight = parseInt(fontWeight);
    if (fontWeight >= 700) {
      style.bold = true;
    }
  }

  if (opts.formatCellStyle !== undefined) {
    opts.formatCellStyle(style, cell);
  }

  for (var key in style) {
    return style;
  }

  return null;
}

var formatCellStyleOption = {
  fontSize: 'font.sz',
  fontFamily: 'font.name',
  bold: 'font.bold',
  underline: 'font.underline',
  strike: 'font.strike',
  italic: 'font.italic',
  color: 'font.color.rgb',
  align: 'alignment.horizontal',
  numFmt: 'numFmt'
};

function formatCellStyle(style) {
  var cellStyle = {};
  for (var key in style) {
    var value = style[key];
    var attrName = formatCellStyleOption[key];
    if (value === undefined || attrName === undefined) {
      continue;
    }
    _.set(cellStyle, attrName, value);
  }
  return cellStyle;
}

function generateArray(table, opts) {
  var out = [];
  var rows;
  var $table = $(table);
  if (!$table.is('tr')) {
    rows = $table[0].querySelectorAll('tr');
  } else {
    rows = [];
    for (var i = 0; i < $table.length; i++) {
      rows.push($table[i]);
    }
  }

  var fomratTableRow = opts.fomratTableRow;
  if (fomratTableRow !== undefined) {
    rows = fomratTableRow(rows);
  }

  var ranges = [];
  var startCell = opts.startCell;
  var startR = 0;
  var startC = 0;

  if (startCell !== undefined) {
    startCell = getExcelStartCell(startCell);
    startR = startCell[0];
    startC = startCell[1];
  }
  var tableTitle = opts.tableTitle;
  if (tableTitle !== undefined) {
    if (typeof tableTitle === "string") {
      startR++;
      out.push([{
        value: tableTitle
      }]);
    } else {
      var colspan = tableTitle.colspan || 1;
      var rowspan = tableTitle.rowspan || 1;
      if (rowspan !== 1 || colspan !== 1) {
        ranges.push({
          s: {
            r: startR,
            c: startC
          },
          e: {
            r: startR + rowspan - 1,
            c: startC + colspan - 1
          }
        });
        startR += rowspan;
        var tableTitleStyle = _.cloneDeep(tableTitle);
        delete tableTitleStyle.rowspan;
        delete tableTitleStyle.colspan;
        delete tableTitleStyle.value;

        out.push([{
          value: tableTitle.value,
          style: tableTitleStyle
        }]);
      }
    }
  }

  for (var R = 0; R < rows.length; ++R) {
    var outRow = [];
    var row = rows[R];
    var columns;
    columns = row.querySelectorAll('td,th');

    for (var C = 0; C < columns.length; ++C) {
      var cell = columns[C];
      var colspan = cell.getAttribute('colspan');
      var rowspan = cell.getAttribute('rowspan');
      var cellValue = cell.innerText.trim();
      if (cellValue !== "" && cellValue == +cellValue) cellValue = +cellValue;

      //Skip ranges
      ranges.forEach(function (range) {
        var rangeStartR = range.s.r - startR;
        var rangeStartC = range.s.c - startC;
        var rangeEndR = range.e.r - startR;
        var rangeEndC = range.e.c - startC;

        if (R >= rangeStartR && R <= rangeEndR && outRow.length >= rangeStartC && outRow.length <= rangeEndC) {
          for (var i = 0; i <= rangeEndC - rangeStartC; ++i) outRow.push(null);
        }
      });

      //Handle Row Span
      if (rowspan || colspan) {
        rowspan = rowspan || 1;
        colspan = colspan || 1;
        if (typeof rowspan === 'string') {
          rowspan = Number(rowspan);
        }

        if (typeof colspan === 'string') {
          colspan = Number(colspan);
        }

        if (rowspan !== 1 || colspan !== 1) {
          ranges.push({
            s: {
              r: R + startR,
              c: outRow.length + startC
            },
            e: {
              r: R + startR + rowspan - 1,
              c: outRow.length + startC + colspan - 1
            }
          });
        }
      };

      //Handle Value
      if (cellValue === "") {
        outRow.push(null);
      } else {
        style = this.getCellStyle(cell, opts);

        var rowData = {
          value: cellValue
        };
        if (style !== null) {
          rowData.style = style;
        }
        outRow.push(rowData);
      }

      //Handle Colspan
      if (colspan)
        for (var k = 0; k < colspan - 1; ++k) outRow.push(null);
    }
    out.push(outRow);
  }
  return [out, ranges];
};

function datenum(v, date1904) {
  if (date1904) v += 1462;
  var epoch = Date.parse(v);
  return (epoch - new Date(Date.UTC(1899, 11, 30))) / (24 * 60 * 60 * 1000);
}

function Workbook() {
  if (!(this instanceof Workbook)) return new Workbook();
  this.SheetNames = [];
  this.Sheets = {};
}

function getExcelStartCell(startCell) {
  var startR = 0;
  var startC = 0;

  switch (typeof startCell) {
    case 'number':
      startR = startCell;
      break;
    case 'string': {
      var len = startCell.length;
      var index = 0;
      for (var i = index; i < len; i++) {
        var num = startCell.charCodeAt(index) - 64;
        if (num < 1 || num > 26) {
          break;
        }
        startC = startC * 26 + num;
        index++;
      }
      startC--;

      for (var i = index; i < len; i++) {
        var num = startCell.charCodeAt(index) - 48;
        if (num < 0 || num > 9) {
          break;
        }
        startR = startR * 10 + num;
        index++;
      }
      startR--;
      break;
    }
    default:
      startR = startCell.r;
      startC = startCell.c
  }

  return [startR, startC];
}

function sheet_from_array_of_arrays(data, opts) {
  opts = opts || {};
  var startCell = opts.startCell;
  var startR = 0;
  var startC = 0;
  if (startCell !== undefined) {
    startCell = getExcelStartCell(startCell);
    startR = startCell[0];
    startC = startCell[1];
  }

  var ws = {};
  var range = {
    s: {
      c: 10000000,
      r: 10000000
    },
    e: {
      c: 0,
      r: 0
    }
  };

  for (var R = 0; R != data.length + startR; ++R) {
    if (range.s.r > R) range.s.r = R;
    if (range.e.r < R) range.e.r = R;
    if (R < startR) {
      continue;
    }
    var dataR = R - startR;
    for (var C = 0; C != data[dataR].length + startC; ++C) {
      if (range.s.c > C) range.s.c = C;
      if (range.e.c < C) range.e.c = C;
      if (C < startC) {
        continue;
      }
      var dataC = C - startC;
      var cellData = data[dataR][dataC];
      var value = null;
      if (cellData) {
        value = cellData.value;
        var indent = _.get(cellData, 'style.indent');
        if (indent !== undefined && indent > 0) {
          value = _.padStart(value, value.length + indent);
        }
      }

      var cell = {
        v: value
      };
      if (cell.v == null) continue;
      var cell_ref = XLSX.utils.encode_cell({
        c: C,
        r: R
      });

      if (typeof cell.v === 'number') cell.t = 'n';
      else if (typeof cell.v === 'boolean') cell.t = 'b';
      else if (cell.v instanceof Date) {
        cell.t = 'n';
        cell.z = XLSX.SSF._table[14];
        cell.v = datenum(cell.v);
      } else cell.t = 's';

      if (cellData) {
        var cellStyle = cellData.style;
        if (cellStyle !== undefined) {
          cellStyle = formatCellStyle(cellStyle);
          cell.s = cellStyle;
        }
      }

      ws[cell_ref] = cell;
    }
  }
  if (range.s.c < 10000000) ws['!ref'] = XLSX.utils.encode_range(range);
  return ws;
}

function s2ab(s) {
  var buf = new ArrayBuffer(s.length);
  var view = new Uint8Array(buf);
  for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
  return buf;
}

function export_table_to_excel(table, defaultTitle, opts) {
  opts = opts || {};
  var oo = generateArray(table, opts);
  var ranges = oo[1];

  /* original data */
  var data = oo[0];
  var ws_name = opts.sheetName || "SheetJS";
  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data, opts);

  /* add ranges to worksheet */
  var cols = [];
  var colWidth = opts.colWidth || [];
  for (var i = 0; i < colWidth.length; i++) {
    var width = colWidth[i];
    cols.push({
      wpx: width
    });
  }
  ws['!cols'] = cols;
  ws['!merges'] = ranges;

  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var title = defaultTitle || '列表';
  var wbout = XLSX.write(wb, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  });

  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), title + ".xlsx")
}

function export_json_to_excel(th, jsonData, defaultTitle, opts) {

  /* original data */

  var data = jsonData;
  opts = opts || {};
  data.unshift(th);
  var ws_name = opts.sheetName || "SheetJS";

  var wb = new Workbook(),
    ws = sheet_from_array_of_arrays(data, opts);


  /* add worksheet to workbook */
  wb.SheetNames.push(ws_name);
  wb.Sheets[ws_name] = ws;

  var wbout = XLSX.write(wb, {
    bookType: 'xlsx',
    bookSST: false,
    type: 'binary'
  });
  var title = defaultTitle || '列表';
  saveAs(new Blob([s2ab(wbout)], {
    type: "application/octet-stream"
  }), title + ".xlsx")
}
